/*
 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
 * http://www.gnu.org/licenses/lgpl-3.0.html
 */

#ifndef PROJECTLOADER_HOOKS_H
#define PROJECTLOADER_HOOKS_H

#include "settings.h"

class TiXmlElement;
class cbProject;

/**
 * Provides static functions to add hooks to the project loading/saving procedure.
 * 提供静态函数以向项目加载/保存过程添加钩子.
 * */
namespace ProjectLoaderHooks
{
    /**
     * Abstract base hook functor interface.
     * 抽象基钩子函子(仿函数)接口.
     * */

    class DLLIMPORT HookFunctorBase
    {
        public:
            virtual ~HookFunctorBase(){}
            virtual void Call(cbProject*, TiXmlElement*, bool) const = 0;
    };

    /** Functor class for use as a project loading/saving hook.
      * Passed as the first parameter in RegisterHook() and
      * UnregisterHook().
      *
      * example:
      * ProjectLoaderHooks::HookFunctorBase* myhook = new ProjectLoaderHooks::HookFunctor<MyClass>(this, &MyClass::OnHookCalled);
      * int id = ProjectLoaderHooks::RegisterHook(myhook);
      * ...
      * (and before your class' destruction - or earlier):
      * ProjectLoaderHooks::UnregisterHook(id, true);
      *
      * Member functions used as hook callbacks must have the following signature:
      * void YourFunctionName(cbProject*, TiXmlElement*, bool)
      *
      * Use normal TinyXML procedures to work with the TiXmlElement* argument.
      * The isLoading argument is true if your hook is called when the project is being loaded,
      * and false when the project is saved.
      *
      * 函子(仿函数)类,用作项目加载/保存挂钩.作为RegisterHook()和UnregisterHook()中的第一个参数传递
      * 如:
      * ProjectLoaderHooks::HookFunctorBase* myhook = new ProjectLoaderHooks::HookFunctor<MyClass>(this, &MyClass::OnHookCalled);
      * int id = ProjectLoaderHooks::RegisterHook(myhook);
      * ...
      * (在你的类被销毁之前,或者更早):
      * ProjectLoaderHooks::UnregisterHook(id, true);
      * 用作钩子回调的成员函数必须具有以下签名:
      * void YourFunctionName(cbProject*, TiXmlElement*, bool)
      *
      * 使用正常的TinyXML过程来处理tixmlement*参数.
      * 如果在加载项目时调用钩子,isLoading参数为true,而在保存项目时为false.
      *
      */
    template<class T> class HookFunctor : public HookFunctorBase
    {
        public:
            typedef void (T::*Func)(cbProject*, TiXmlElement*, bool);
            HookFunctor(T* obj, Func func) : m_pObj(obj), m_pFunc(func)
            { ; }
            virtual void Call(cbProject* project, TiXmlElement* elem, bool isLoading) const
            {
                if (m_pObj && m_pFunc)
                    (m_pObj->*m_pFunc)(project, elem, isLoading);
            }
        protected:
            T* m_pObj;
            Func m_pFunc;
    };

    /**
     * Register a project loading/saving hook.
      * 参数说明: functor The functor to use as a callback.
      * 返回值:  An ID. Use this to unregister your hook later.
      *
      * 注册项目加载/保存挂钩.
      * 参数说明: functor 要用作回调的函子(仿函数).
      * 返回值: 一个ID. 以后用你的钩子注销.
      */
    extern DLLIMPORT int RegisterHook(HookFunctorBase* functor);
    /**
     * Unregister a previously registered project loading/saving hook.
      * 参数说明: id The hook's ID. You should have the ID from when RegisterHook() was called.
      * 参数说明: deleteHook If true, the hook will be deleted (default). If not, it's
      * up to you to delete it.
      * 返回值:  The functor. If @c deleteHook was true, it always returns NULL.
      *
     * 注销以前注册的项目加载/保存挂钩.
      * 参数说明: id 钩子的ID.应该具有调用RegisterHook()时的ID.
      * 参数说明: deleteHook如果为true,则钩子将被删除(默认).如果没有,就由你来删除它.
      * 返回值:  仿函数. 如果参数deleteHook为true,则始终返回NULL.
      */
    extern DLLIMPORT HookFunctorBase* UnregisterHook(int id, bool deleteHook = true);
    /**
     * Are there any hooks registered?
      * 返回值:  True if any hooks are registered, false if none.
      *
     * 有登记的钩子吗?
      * 返回值:  如果注册了任何钩子,则为True；如果没有,则为false.
      */
    extern DLLIMPORT bool HasRegisteredHooks();
    /**
     * Call all registered hooks using the supplied parameters.
      * This is called by ProjectLoader.
      * 参数说明: project The project in question.
      * 参数说明: elem The XML element under which the called hook can read/write.
      * 参数说明: isLoading True if the project is being loaded, false if being saved.
      *
      * 使用提供的参数调用所有注册的钩子.
      * 这是由ProjectLoader调用的.
      * 参数说明: project 正在讨论的项目.
      * 参数说明: elem 被调用的钩子可以在其下读/写的XML元素.
      * 参数说明: 如果正在加载项目,则isLoading为True；如果正在保存,则为false.
      *
      */
    extern DLLIMPORT void CallHooks(cbProject* project, TiXmlElement* elem, bool isLoading);
}

#endif // PROJECTLOADER_HOOKS_H
